package com.NetSunWeiQin.chapter05.httpserver;

import java.io.*;
import java.net.*;
import java.nio.channels.*;

/**
 * 文件形式的响应正文 ;  即渲染 html 给 浏览器 ;
* */
public class FileContent implements Content {
    //假定文件的根目录为"root"
    private static File ROOT = new File("root");
    private File file;

    public  FileContent(URI uri) {
        String  s = File.separator;
//        String filePath = ROOT + uri.getPath().replace("/", s);
        String filePath = ROOT + uri.getPath() ;
        ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
        if (filePath.contains("html")){
            filePath =   filePath.replaceAll("html" , "htm") ;
        }
        URL resource = contextClassLoader.getResource(filePath);
        filePath = resource != null ? resource.getPath() : "" ;
        this.file = new File(filePath);
    }

    private String type = null;

    /* 确定文件类型 */
    public String type() {
        if (type != null) return type;
        String nm = file.getName();
        if (nm.endsWith(".html") || nm.endsWith(".htm"))
            type = "text/html; charset=utf-8";  //HTML网页
        else if ((nm.indexOf('.') < 0) || nm.endsWith(".txt"))
            type = "text/plain; charset=utf-8";  //文本文件
        else
            type = "application/octet-stream";  //应用程序
        return type;
    }

    private FileChannel fileChannel = null;
    private long length = -1;  //文件长度
    private long position = -1; //文件的当前位置

    public long length() {
        return length;
    }

    /* 创建FileChannel对象*/
    public void prepare() throws IOException {
        if (fileChannel == null)
            fileChannel = new RandomAccessFile(file, "r").getChannel();
        length = fileChannel.size();
        position = 0;
    }

    /* 发送正文，如果发送完毕，就返回false，否则返回true */
    public boolean send(ChannelIO channelIO) throws IOException {
        if (fileChannel == null)
            throw new IllegalStateException();
        if (position < 0)
            throw new IllegalStateException();

        if (position >= length) {
            return false;  //如果发送完毕，就返回false
        }

        position += channelIO.transferTo(fileChannel, position, length - position);
        return (position < length);
    }

    public void release() throws IOException {
        if (fileChannel != null) {
            fileChannel.close();  //关闭fileChannel
            fileChannel = null;
        }
    }
}

